package com.freedom.rpc.thrift.server.utils;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.freedom.rpc.thrift.common.utils.LoggerUtils;

import org.apache.log4j.LogManager;

/**
 * 
 * @author zhiqiang.liu
 * @2016年1月1日
 *
 */

public class MyServerProperties {
	// 以下为全局需要
	private static final Logger logger = LogManager.getLogger(MyServerProperties.class);

	// 测试
	public static void main(String[] args) {
		// just for test
		MyServerProperties property = MyServerProperties.getInstance();
		LoggerUtils.debug(logger, property.toString());
	}

	public static MyServerProperties getInstance() {
		return myProperties;
	}

	//
	private static MyServerProperties myProperties = null;// 全局单例变量，一开始就存在
	static {// 静态块里，只加载一次

		Properties props = new Properties();
		try {
			InputStream in = new BufferedInputStream(new FileInputStream(SERVER_CONFIG.SERVER_CONFIG_FILE));
			// Thread.currentThread().getContextClassLoader().getResourceAsStream(MyConstants.CONFIG_FILE);
			props.load(in);
			in.close();
		} catch (Exception e) {
			// logger.error(e.toString());
			LoggerUtils.error(logger, "fail to read config file " + SERVER_CONFIG.SERVER_CONFIG_FILE);
			System.exit(-1);
		}
		// 读取值
		LoggerUtils.debug(logger, "succeed to read config file " + SERVER_CONFIG.SERVER_CONFIG_FILE);
		// netty
		int port = Integer.parseInt(props.getProperty(SERVER_CONFIG.SERVER_PORT, "10000"));
		int acceptThreads = Integer.parseInt(props.getProperty(SERVER_CONFIG.ACCEPT_THREADS, "1"));
		int selectThreads = Runtime.getRuntime().availableProcessors()
				* Integer.parseInt(props.getProperty(SERVER_CONFIG.SELECT_THREADS, "2").trim());// 2倍cpu
		// worker
		int workerThreads = Runtime.getRuntime().availableProcessors()
				* Integer.parseInt(props.getProperty(SERVER_CONFIG.WORKER_THREADS, "2").trim());// 2倍cpu
		// size
		int acceptedQueueSize = Integer.parseInt(props.getProperty(SERVER_CONFIG.QUEUE_SIZE, "10000").trim());
		props.clear();
		props = null;
		// 构造新的对象
		myProperties = new MyServerProperties(port, acceptThreads, selectThreads, acceptedQueueSize, workerThreads);
		LoggerUtils.info(logger, "succeed to create my properties object ");
		LoggerUtils.info(logger, "cpu - " + Runtime.getRuntime().availableProcessors());
	}

	// 私有属性开始//////////////////////////////////////////////////////////////////
	// thrift
	private int port;
	private int accpetThreads;
	private int selectorThreads;
	private int queueSize;
	private int workerThreads;

	private MyServerProperties() {// 私有方法，保证单例
	}

	private MyServerProperties(int port, int aThreads, int sThreads, int qSize, int wThreads) {
		// used by netty
		this.port = port;
		this.accpetThreads = aThreads;
		this.selectorThreads = sThreads;
		this.queueSize = qSize;
		this.workerThreads = wThreads;
	}

	public int getPort() {
		return port;
	}

	public int getAccpetThreads() {
		return accpetThreads;
	}

	public int getSelectorThreads() {
		return selectorThreads;
	}

	public int getWorkerThreads() {
		return workerThreads;
	}

	public String toString() {
		StringBuilder strBuilder = new StringBuilder("");
		strBuilder.append(SERVER_CONFIG.SERVER_PORT).append(": ").append(port).append(" ");
		strBuilder.append(SERVER_CONFIG.ACCEPT_THREADS).append(": ").append(accpetThreads).append(" ");
		strBuilder.append(SERVER_CONFIG.SELECT_THREADS).append(": ").append(selectorThreads).append(" ");
		strBuilder.append(SERVER_CONFIG.QUEUE_SIZE).append(": ").append(queueSize).append(" ");
		strBuilder.append(SERVER_CONFIG.WORKER_THREADS).append(": ").append(workerThreads).append(" ");
		return strBuilder.toString();
	}

	public int getQueueSize() {
		return queueSize;
	}

	// 内部类
	static class SERVER_CONFIG {
		public static String SERVER_CONFIG_FILE = System.getProperty("serverProperties",
				"src/main/resources/server.properties");
		public static String SERVER_PORT = "port";
		public static String ACCEPT_THREADS = "accept_threads";
		public static String SELECT_THREADS = "select_threads";
		public static String WORKER_THREADS = "work_threads";
		public static String QUEUE_SIZE = "accepted_queue_size";
	}
}
